package com.tanhua.app.service;

import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.tanhua.api.db.UserApi;
import com.tanhua.api.db.UserInfoApi;
import com.tanhua.db.User;
import com.tanhua.db.UserInfo;
import com.tanhua.template.AipFaceTemplate;
import com.tanhua.template.OssTemplate;
import com.tanhua.template.SmsTemplate;
import com.tanhua.vo.UserInfoVo;
import org.apache.dubbo.config.annotation.Reference;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.multipart.MultipartFile;
import utils.JwtUtil;

import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

@Service
public class UserService {

    //用户接口
    @Reference
    private UserApi userApi;

    //用户详细信息接口
    @Reference
    private UserInfoApi userInfoApi;


    //短息模版
    @Autowired
    private SmsTemplate smsTemplate;

    //
    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    //人脸识别api
    @Autowired
    private AipFaceTemplate aipFaceTemplate;

    //oss图片上传
    @Autowired
    private OssTemplate ossTemplate;

    /**
     * 注册 保存用户
     * @param user 用户信息
     * @return 用户 id
     */
    public ResponseEntity saveUser(@RequestBody User user){
        Long id = userApi.saveUser(user);
        return ResponseEntity.ok(id);
    }

    /**
     * 根据手机号做用户查询
     * @param phone 用户手机号
     * @return  用户信息
     */
    public ResponseEntity findByPhone(String  phone){
        User user = userApi.findByPhone(phone);
        return ResponseEntity.ok(user);
    }

    /**
     * 手机登录发送验证码
     * @param phone 用户手机号
     * @return  null
     */
    public ResponseEntity login(String phone){

        // 2 获取随机6位数
        //String code = RandomUtil.randomNumbers(6);
        String code = "123456";
        // 3 调用阿里云工具类抽成的启动器模板
        System.out.println("登入手机号: "+phone);
        System.out.println("登入验证码: "+code);
        smsTemplate.sendSms(phone,code);
        //4  放入redis中（设置过期时间）
        stringRedisTemplate.opsForValue().set("SMS_CODE_"+phone,code,10, TimeUnit.MINUTES);
        //扩展取：String value=stringRedisTemplate.opsForValue().get("key");
        //5 返回值
        return ResponseEntity.ok(null);

    }

    /**
     * 注册/登录
     * @param phone 手机号
     * @param yzm   验证码
     * @return 标记令牌，是否是新账号 true：新账号 flag：老账号
     */
    public ResponseEntity loginVerification(String phone, String yzm) {


        //获取 redis 中的 token 用户身份验证的标记
        //1 获取redis中的验证码
        String redis_yzm = stringRedisTemplate.opsForValue().get("SMS_CODE_"+phone);
        //2 对比和页面用户写入的验证码
        if(!StrUtil.equals(yzm,redis_yzm)){
            //3 不一致--直接给错误信息

            return ResponseEntity.status((500)).body("验证码错误");

        }
        //优化验证码：用完即删
        //将 token 从 redis 中删除
        stringRedisTemplate.delete("SMS_CODE_"+phone);
        //4 一致--带着手机号去查询
        User user = userApi.findByPhone(phone);
        //6 查到了（老用户） return false
        Boolean flag=false;
        //5 没查到（新用户）--注册 return true
        if(user==null){
            user = new User();
            //设置手机号
            user.setPhone(phone);
             //注册  保存用户返回Id
            Long id = userApi.saveUser(user);
            //添加Id
            user.setId(id);
            flag=true;
        }
        System.out.println("登入/注册 用户信息： "+user.toString());
        //将当前用户加密成一串字符串token        电话+tanhua
        String token = JwtUtil.createToken(user.getPhone(), "tanhua");
        //当前用户对象转成json
        String user_json = JSON.toJSONString(user);
        stringRedisTemplate.opsForValue().set( "TOKEN_"+token,user_json,1,TimeUnit.DAYS);

        //返回json
        Map json_map=new HashMap<String,Object>();
        //标记令牌
        json_map.put("token",token); //待会来优化
        //是否是新账号 true：新账号 flag：老账号
        json_map.put("isNew",flag);
        return ResponseEntity.ok(json_map);

    }

    /**
     * 完善用户信息上集
     * @param userInfo  用户详细信息
     * @param token     标记令牌
     * @return
     */
    public ResponseEntity loginReginfo(UserInfo userInfo, String token) {

        //获取 redis 中的 token
        String user_json = stringRedisTemplate.opsForValue().get("TOKEN_"+token);
        // 将从页面获取的字节输入流中的字符数据解析成指定类型JavaBean
        User user = JSON.parseObject(user_json, User.class);
        // 2 将登录用户的id赋值给userInfo的id (让主键一一对应)
        System.out.println("用户id: "+user.getId());
        userInfo.setId(user.getId());
        // 3 调用服务方法做保存   保存数据到用户详细信息表
        userInfoApi.saveUserInfo(userInfo);

        return ResponseEntity.ok(null);

    }

    /**
     * 从redis中根据token获取当前登录用户信息（user）
     * @param token 标记令牌
     * @return      用户信息
     */
    public User findByToken(String token) {
        String user_json = stringRedisTemplate.opsForValue().get("TOKEN_" + token);
        User user = JSON.parseObject(user_json, User.class);
        return user;
    }

    /**
     * 完善用户信息下集
     * @param headPhoto
     * @param token
     * @return
     */
    public ResponseEntity head(MultipartFile headPhoto, String token) throws IOException {

        boolean flag = aipFaceTemplate.detect(headPhoto.getBytes());
        if(flag==false){
            //识别失败
            return   ResponseEntity.status(500).body("人脸识别失败~");
        }
        // 传递图片到oss      形参1： 文件名  形参1：输入流
        String url = ossTemplate.upload(headPhoto.getOriginalFilename(), headPhoto.getInputStream());
        // 根据token获取用户id
        User user = findByToken(token);
        //根据id修改userInfo的图片oss地址
        UserInfo userInfo = new UserInfo();
        //设置用户id
        userInfo.setId(user.getId());
        //设置头像
        userInfo.setAvatar(url);
        //设置封面图片
        userInfo.setCoverPic(url);

        //修改userInfo
        userInfoApi.updateUserInfo(userInfo);
        return ResponseEntity.ok(null);
    }

    /**
     * 根据Id做查询
     * @param id
     * @return
     */
    public ResponseEntity findUserInfoVo(Long id) {
        //1.根据id 查询用户的详细信息
        UserInfo userInfo = userInfoApi.findById(id);
        //2.把用户的详细信息 存储到 实体类中
        UserInfoVo userInfoVo = new UserInfoVo();
        //3.数据拷贝
        BeanUtils.copyProperties(userInfo, userInfoVo);
        //4.返回 userInfoVo 用户详细信息
        System.out.println("用户回显数据："+userInfoVo.toString());
        return ResponseEntity.ok(userInfoVo);
    }
}
